package performace_test;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

import map.CandyAVLMap;
import map.CandyBSTMap;
import map.CandyHashMap;
import map.CandyLinkedListMap;
import map.CandyMap;
import map.CandyRedBlackMap;
import util.FileOperation;

/**
 * 
 * @Title: SetPerformaceTest.java 
 * @Package performace_test 
 * @Description: CandyBSTMap和CandyLinkedListMap性能测试以及对比
 * @author CandyWall   
 * @date 2021年1月6日 下午18:00:49 
 * @version V1.0
 */
public class MapPerformaceTest {
    /**
     * 测试往映射中添加一组随机元素
     * @return
     */
    public static double testMapOfAdd(ArrayList<Integer> nums, CandyMap<Integer, Object> map) {
        // 记录开始时间
        long startTime = System.nanoTime();
        for(Integer num : nums) {
            map.add(num, null);
        }
        // 返回耗时
        return (System.nanoTime() - startTime) / 1000_000_000.0;
    }
    /**
     * 测试映射添加元素的性能，返回总共消耗的时间（秒）
     * @param queue     ：需要进行性能测试的队列
     * @param opCount   ：需要进行出入队的次数
     * @return
     */
    public static double testMap(ArrayList<String> words, CandyMap<String, Integer> map) {
        // 记录开始时间
        long startTime = System.nanoTime();
        for(String word : words) {
            // 如果映射中不包含这个单词，说明这个单词第1次出现，
            // 那么将这个单词添加到映射中
            if(!map.contains(word)) {
                map.add(word, 1);
            } else {
                map.set(word, map.get(word) + 1);
            }
        }
        for(String word : words) {
            map.contains(word);
        }
        System.out.println("单词总数：" + words.size());
        System.out.println("不同单词数量：" + map.getSize());
        System.out.println("pride出现的次数：" + map.get("pride"));
        System.out.println("prejudice出现的次数：" + map.get("prejudice"));
        // 返回耗时
        return (System.nanoTime() - startTime) / 1000_000_000.0;
    }
    
    // 从文件中读取到所有的单词，并以ArrayList<String>方式返回
    private static ArrayList<String> readWordsFromFile(String filePath) {
        ArrayList<String> words = new ArrayList<>();
        if(!FileOperation.readFile(filePath, words)) {
            // 加载失败
            try {
                throw new FileNotFoundException("找不到文件");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } 
        return words;
    }
    
    public static void main(String[] args) {
        String filePath = "testData/pride-and-prejudice.txt";
        ArrayList<String> words = readWordsFromFile(filePath);
        // Collections.sort(words);
        
        // 进行性能测试
        System.out.println("+++++++++++单词统计性能测试++++++++++++");
        /*double cost1 = testMap(words, new CandyLinkedListMap<String, Integer>());
        System.out.println("CandyLinkedListMap耗时：" + cost1 + " 秒");*/
        System.out.println("--------------------------------------");
        double cost2 = testMap(words, new CandyBSTMap<String, Integer>());
        System.out.println("CandyBSTMap耗时：" + cost2 + " 秒");
        System.out.println("--------------------------------------");
        double cost3 = testMap(words, new CandyAVLMap<String, Integer>());
        System.out.println("CandyAVLMap耗时：" + cost3 + " 秒");
        System.out.println("--------------------------------------");
        double cost4 = testMap(words, new CandyRedBlackMap<String, Integer>());
        System.out.println("CandyRedBlackMap耗时：" + cost4 + " 秒");
        System.out.println("--------------------------------------");
        double cost5 = testMap(words, new CandyHashMap<String, Integer>());
        System.out.println("CandyHashMap1耗时：" + cost5 + " 秒");
        double cost6 = testMap(words, new CandyHashMap<String, Integer>(131071));
        System.out.println("CandyHashMap2耗时：" + cost6 + " 秒");
        /*System.out.println("--------------------------------------");
        System.out.println("CandyBSTMap和CandyLinkedListMap性能比（性能和耗时成反比）：" + cost2 / cost1);*/
        
        ArrayList<Integer> nums = new ArrayList<>();
        Random random = new Random();
        for(int i = 0; i < 1000_0000; i++) {
            nums.add(random.nextInt(Integer.MAX_VALUE));
        }
        /*System.out.println("+++++++++++++++随机数添加性能测试+++++++++++++++++++");
        double cost5 = testMapOfAdd(nums, new CandyLinkedListMap<Integer, Object>());
        System.out.println("CandyLinkedListMap耗时：" + cost5 + " 秒");
        System.out.println("--------------------------------------");
        double cost6 = testMapOfAdd(nums, new CandyBSTMap<Integer, Object>());
        System.out.println("CandyBSTMap耗时：" + cost6 + " 秒");
        System.out.println("--------------------------------------");*/
        /*double cost7 = testMapOfAdd(nums, new CandyAVLMap<Integer, Object>());
        System.out.println("CandyAVLMap耗时：" + cost7 + " 秒");
        System.out.println("--------------------------------------");
        double cost8 = testMapOfAdd(nums, new CandyRedBlackMap<Integer, Object>());
        System.out.println("CandyRedBlackMap耗时：" + cost8 + " 秒");
        System.out.println("--------------------------------------");
        double cost9 = testMapOfAdd(nums, new CandyHashMap<Integer, Object>());
        System.out.println("CandyHashMap耗时：" + cost9 + " 秒");*/
    }
}
